package cn.edu.ncut.cs.springboot.petmanagementsystem.controller;

import cn.edu.ncut.cs.springboot.petmanagementsystem.Util.JwtUtil;
import cn.edu.ncut.cs.springboot.petmanagementsystem.common.PageResult;
import cn.edu.ncut.cs.springboot.petmanagementsystem.common.Result;
import cn.edu.ncut.cs.springboot.petmanagementsystem.pojo.PetHealthRecord;
import cn.edu.ncut.cs.springboot.petmanagementsystem.service.PetHealthService;
import cn.edu.ncut.cs.springboot.petmanagementsystem.vo.PetHealthRecordVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@Slf4j
@RestController
@RequestMapping("/pet-health")
@Tag(name = "宠物健康检测模块")
public class PetHealthController {

    @Autowired
    private PetHealthService petHealthService;
    
    @Autowired
    private cn.edu.ncut.cs.springboot.petmanagementsystem.mapper.PetHealthRecordMapper petHealthRecordMapper;
    
    // ==================== 管理后台接口 ====================
    
    @Operation(summary = "管理员查询宠物健康检测记录（支持动态查询）")
    @GetMapping({"/admin/list", "/admin/pet-health/list"})
    // @PreAuthorize("hasRole('ADMIN')")  // 如需启用权限，取消注释
    public PageResult<PetHealthRecordVO> getAdminPetHealthList(
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") Integer pageNum,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer pageSize,
            @Parameter(description = "宠物ID") @RequestParam(required = false) Long petId,
            @Parameter(description = "宠物名称（模糊查询）") @RequestParam(required = false) String petName,
            @Parameter(description = "检测类型") @RequestParam(required = false) String checkType,
            @Parameter(description = "健康状态") @RequestParam(required = false) Integer healthStatus,
            @Parameter(description = "检测医生ID") @RequestParam(required = false) Long doctorId,
            @Parameter(description = "医生姓名（模糊查询）") @RequestParam(required = false) String doctorName,
            @Parameter(description = "检测开始日期") @RequestParam(required = false) String startDate,
            @Parameter(description = "检测结束日期") @RequestParam(required = false) String endDate,
            @Parameter(description = "最小体重(kg)") @RequestParam(required = false) Double minWeight,
            @Parameter(description = "最大体重(kg)") @RequestParam(required = false) Double maxWeight,
            @Parameter(description = "最低体温(°C)") @RequestParam(required = false) Double minTemperature,
            @Parameter(description = "最高体温(°C)") @RequestParam(required = false) Double maxTemperature,
            @Parameter(description = "最低心率(次/分)") @RequestParam(required = false) Integer minHeartRate,
            @Parameter(description = "最高心率(次/分)") @RequestParam(required = false) Integer maxHeartRate,
            @Parameter(description = "排序字段") @RequestParam(required = false) String orderBy,
            @Parameter(description = "排序方向") @RequestParam(required = false, defaultValue = "desc") String order
    ) {
        try {
            log.info("管理员查询宠物健康检测记录 - pageNum: {}, pageSize: {}, petId: {}, petName: {}, checkType: {}, healthStatus: {}", 
                     pageNum, pageSize, petId, petName, checkType, healthStatus);
            log.info("筛选条件 - 医生: {} (ID: {}), 日期: [{} - {}], 体重: [{} - {}], 体温: [{} - {}], 心率: [{} - {}]", 
                     doctorName, doctorId, startDate, endDate, minWeight, maxWeight, minTemperature, maxTemperature, minHeartRate, maxHeartRate);
            
            com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<PetHealthRecord> queryWrapper = 
                    new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
            
            // 1. 宠物ID
            if (petId != null) {
                queryWrapper.eq(PetHealthRecord::getPetId, petId);
            }
            
            // 2. 宠物名称（需要关联查询，这里先通过petId列表实现）
            if (org.springframework.util.StringUtils.hasText(petName)) {
                // 如果同时有petId，则不需要额外查询
                if (petId == null) {
                    // 需要通过Service查询宠物ID列表，这里简化处理，使用SQL LIKE
                    // 注意：如果Pet表有petName字段，可以通过子查询实现
                    // 这里假设可以通过关联查询实现，实际可能需要自定义SQL
                    queryWrapper.apply("pet_id IN (SELECT id FROM pets WHERE pet_name LIKE {0})", 
                                      "%" + petName + "%");
                }
            }
            
            // 3. 检测类型（对应recordType字段，但数据库可能没有，这里通过诊断或症状字段模糊查询）
            if (org.springframework.util.StringUtils.hasText(checkType)) {
                queryWrapper.and(wrapper -> 
                    wrapper.like(PetHealthRecord::getDiagnosis, checkType)
                           .or()
                           .like(PetHealthRecord::getSymptoms, checkType)
                );
            }
            
            // 4. 健康状态
            if (healthStatus != null) {
                queryWrapper.eq(PetHealthRecord::getHealthStatus, healthStatus);
            }
            
            // 5. 医生ID（如果数据库有doctorId字段，否则通过veterinarian姓名查询）
            // 注意：当前实体只有veterinarian字段，没有doctorId，所以这里通过姓名查询
            if (doctorId != null) {
                // 如果数据库有doctorId字段，使用：queryWrapper.eq(PetHealthRecord::getDoctorId, doctorId);
                // 否则需要通过Service查询医生姓名，再通过姓名查询
                log.warn("doctorId参数暂不支持，请使用doctorName参数");
            }
            
            // 6. 医生姓名（对应veterinarian字段）
            if (org.springframework.util.StringUtils.hasText(doctorName)) {
                queryWrapper.like(PetHealthRecord::getVeterinarian, doctorName);
            }
            
            // 7. 日期范围
            if (org.springframework.util.StringUtils.hasText(startDate)) {
                queryWrapper.ge(PetHealthRecord::getCheckDate, startDate);
            }
            if (org.springframework.util.StringUtils.hasText(endDate)) {
                queryWrapper.le(PetHealthRecord::getCheckDate, endDate);
            }
            
            // 8. 体重范围（忽略0值）
            if (minWeight != null && minWeight > 0) {
                queryWrapper.ge(PetHealthRecord::getWeight, java.math.BigDecimal.valueOf(minWeight));
            }
            if (maxWeight != null && maxWeight > 0) {
                queryWrapper.le(PetHealthRecord::getWeight, java.math.BigDecimal.valueOf(maxWeight));
            }
            
            // 9. 体温范围（忽略0值）
            if (minTemperature != null && minTemperature > 0) {
                queryWrapper.ge(PetHealthRecord::getTemperature, java.math.BigDecimal.valueOf(minTemperature));
            }
            if (maxTemperature != null && maxTemperature > 0) {
                queryWrapper.le(PetHealthRecord::getTemperature, java.math.BigDecimal.valueOf(maxTemperature));
            }
            
            // 10. 心率范围（忽略0值）
            if (minHeartRate != null && minHeartRate > 0) {
                queryWrapper.ge(PetHealthRecord::getHeartRate, minHeartRate);
            }
            if (maxHeartRate != null && maxHeartRate > 0) {
                queryWrapper.le(PetHealthRecord::getHeartRate, maxHeartRate);
            }
            
            // 11. 排序
            if (org.springframework.util.StringUtils.hasText(orderBy)) {
                boolean isAsc = "asc".equalsIgnoreCase(order);
                switch (orderBy.toLowerCase()) {
                    case "checkdate":
                        queryWrapper.orderBy(true, isAsc, PetHealthRecord::getCheckDate);
                        break;
                    case "temperature":
                        queryWrapper.orderBy(true, isAsc, PetHealthRecord::getTemperature);
                        break;
                    case "weight":
                        queryWrapper.orderBy(true, isAsc, PetHealthRecord::getWeight);
                        break;
                    default:
                        queryWrapper.orderByDesc(PetHealthRecord::getCheckDate);
                }
            } else {
                queryWrapper.orderByDesc(PetHealthRecord::getCheckDate);
            }
            
            // 分页查询
            com.baomidou.mybatisplus.extension.plugins.pagination.Page<PetHealthRecord> page = 
                    new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageNum, pageSize);
            com.baomidou.mybatisplus.extension.plugins.pagination.Page<PetHealthRecord> result = 
                    petHealthRecordMapper.selectPage(page, queryWrapper);
            
            log.info("管理员查询健康检测结果 - 总记录数: {}, 当前页: {}, 总页数: {}", 
                     result.getTotal(), result.getCurrent(), result.getPages());
            
            // 转换为VO
            java.util.List<PetHealthRecordVO> voList = new java.util.ArrayList<>();
            for (PetHealthRecord record : result.getRecords()) {
                PetHealthRecordVO vo = petHealthService.getHealthRecordDetailById(record.getId());
                if (vo != null) {
                    voList.add(vo);
                }
            }
            
            com.baomidou.mybatisplus.extension.plugins.pagination.Page<PetHealthRecordVO> voPage = 
                    new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(result.getCurrent(), result.getSize(), result.getTotal());
            voPage.setRecords(voList);
            
            return PageResult.success(voPage);
        } catch (Exception e) {
            log.error("管理员查询健康检测记录失败", e);
            return PageResult.pageError("查询失败: " + e.getMessage());
        }
    }
    
    // ==================== 用户端接口 ====================

    @Operation(summary = "添加宠物健康检测或体检记录")
    @PostMapping("/create")
    public Result<?> createHealthRecord(@RequestBody PetHealthRecord record) {
        try {
            boolean success = petHealthService.createHealthRecord(record);
            return success ? Result.success("添加成功") : Result.error("添加失败");
        } catch (IllegalArgumentException e) {
            return Result.error(e.getMessage());
        } catch (Exception e) {
            log.error("添加健康记录失败", e);
            return Result.error("添加失败: " + e.getMessage());
        }
    }

    @Operation(summary = "查询宠物的健康检测记录")
    @GetMapping("/list")
    public PageResult<PetHealthRecordVO> getHealthRecords(
            @Parameter(description = "宠物ID") @RequestParam(required = false) Long petId,
            @Parameter(description = "宠物名称") @RequestParam(required = false) String petName,
            @Parameter(description = "健康状态") @RequestParam(required = false) Integer status,
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") Integer pageNum,
            @Parameter(description = "每页数量") @RequestParam(defaultValue = "10") Integer pageSize) {
        try {
            IPage<PetHealthRecordVO> page = petHealthService.getHealthRecords(pageNum, pageSize, petId, petName, status);
            return PageResult.success(page);
        } catch (Exception e) {
            log.error("查询健康记录失败", e);
            return PageResult.pageError("查询失败: " + e.getMessage());
        }
    }

    @Operation(summary = "查看单条健康检测详情")
    @GetMapping("/detail/{id}")
    public Result<PetHealthRecordVO> getHealthRecordDetail(
            @Parameter(description = "健康记录ID") @PathVariable Long id) {
        try {
            PetHealthRecordVO record = petHealthService.getHealthRecordDetailById(id);
            if (record != null) {
                return Result.success(record);
            }
            return Result.error("记录不存在");
        } catch (Exception e) {
            log.error("查询健康记录详情失败", e);
            return Result.error("查询失败");
        }
    }

    @Operation(summary = "修改健康记录")
    @PutMapping("/update/{id}")
    public Result<?> updateHealthRecord(
            @Parameter(description = "健康记录ID") @PathVariable Long id,
            @RequestBody PetHealthRecord record) {
        try {
            record.setId(id);
            boolean success = petHealthService.updateHealthRecord(record);
            return success ? Result.success("更新成功") : Result.error("更新失败");
        } catch (Exception e) {
            log.error("更新健康记录失败", e);
            return Result.error("更新失败: " + e.getMessage());
        }
    }

    @Operation(summary = "删除健康检测记录")
    @DeleteMapping("/delete/{id}")
    public Result<?> deleteHealthRecord(
            @Parameter(description = "健康记录ID") @PathVariable Long id) {
        try {
            boolean success = petHealthService.deleteHealthRecord(id);
            return success ? Result.success("删除成功") : Result.error("删除失败");
        } catch (Exception e) {
            log.error("删除健康记录失败", e);
            return Result.error("删除失败: " + e.getMessage());
        }
    }

    @Operation(summary = "上传健康检测报告或相关图片")
    @PostMapping("/report/upload")
    public Result<?> uploadReport(
            @Parameter(description = "文件") @RequestParam("file") MultipartFile file,
            @Parameter(description = "健康记录ID") @RequestParam(required = false) Long recordId) {
        try {
            if (file.isEmpty()) {
                return Result.error("文件不能为空");
            }
            String fileUrl = "/uploads/" + System.currentTimeMillis() + "_" + file.getOriginalFilename();
            return Result.success("上传成功", fileUrl);
        } catch (Exception e) {
            log.error("上传文件失败", e);
            return Result.error("上传失败: " + e.getMessage());
        }
    }

    @Operation(summary = "获取健康记录统计")
    @GetMapping("/statistics/{petId}")
    public Result<?> getHealthStatistics(
            @Parameter(description = "宠物ID") @PathVariable Long petId) {
        try {
            var statistics = petHealthService.getHealthStatistics(petId);
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("获取健康统计失败", e);
            return Result.error("获取失败: " + e.getMessage());
        }
    }

    @Operation(summary = "获取健康提醒列表")
    @GetMapping("/reminders")
    public Result<?> getHealthReminders(@RequestHeader("Authorization") String authHeader) {
        try {
            Long userId = getUserIdFromToken(authHeader);
            if (userId == null) {
                return Result.error("用户未登录");
            }
            var reminders = petHealthService.getHealthReminders(userId);
            return Result.success(reminders);
        } catch (Exception e) {
            log.error("获取健康提醒失败", e);
            return Result.error("获取失败: " + e.getMessage());
        }
    }

    private Long getUserIdFromToken(String authHeader) {
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            String token = authHeader.substring(7);
            return JwtUtil.getUserId(token);
        }
        return null;
    }
}
